1 /*
2 * Copyright 2016-2020 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.springframework.integration.jpa.dsl;
18
19 import java.util.Collections;
20 import java.util.Map;
21
22 import org.springframework.expression.Expression;
23 import org.springframework.integration.dsl.ComponentsRegistration;
24 import org.springframework.integration.dsl.MessageSourceSpec;
25 import org.springframework.integration.expression.ValueExpression;
26 import org.springframework.integration.jpa.core.JpaExecutor;
27 import org.springframework.integration.jpa.inbound.JpaPollingChannelAdapter;
28 import org.springframework.integration.jpa.support.parametersource.ParameterSource;
29
30 /**
31 * A {@link MessageSourceSpec} for a {@link JpaPollingChannelAdapter}.
32 *
33 * @author Artem Bilan
34 *
35 * @since 5.0
36 */
37 public class JpaInboundChannelAdapterSpec
38 extends MessageSourceSpec<JpaInboundChannelAdapterSpec, JpaPollingChannelAdapter>
39 implements ComponentsRegistration {
40
41 protected final JpaExecutor jpaExecutor; // NOSONAR - final
42
43 protected JpaInboundChannelAdapterSpec(JpaExecutor jpaExecutor) {
44 this.jpaExecutor = jpaExecutor;
45 this.target = new JpaPollingChannelAdapter(this.jpaExecutor);
46 }
47
48 /**
49 * Specify the class type which is being used for retrieving entities from the database.
50 * @param entityClass the entity {@link Class} to use
51 * @return the spec
52 */
53 public JpaInboundChannelAdapterSpec entityClass(Class<?> entityClass) {
54 this.jpaExecutor.setEntityClass(entityClass);
55 return this;
56 }
57
58 /**
59 * Specify a JPA query to perform persistent operation.
60 * @param jpaQuery the JPA query to use.
61 * @return the spec
62 */
63 public JpaInboundChannelAdapterSpec jpaQuery(String jpaQuery) {
64 this.jpaExecutor.setJpaQuery(jpaQuery);
65 return this;
66 }
67
68 /**
69 * Specify a native SQL query to perform persistent operation.
70 * @param nativeQuery the native SQL query to use.
71 * @return the spec
72 */
73 public JpaInboundChannelAdapterSpec nativeQuery(String nativeQuery) {
74 this.jpaExecutor.setNativeQuery(nativeQuery);
75 return this;
76 }
77
78 /**
79 * Specify a name a named JPQL based query or a native SQL query.
80 * @param namedQuery the name of the pre-configured query.
81 * @return the spec
82 */
83 public JpaInboundChannelAdapterSpec namedQuery(String namedQuery) {
84 this.jpaExecutor.setNamedQuery(namedQuery);
85 return this;
86 }
87
88 /**
89 * If set to 'true', the retrieved objects are deleted from the database upon
90 * being polled. May not work in all situations, e.g. for Native SQL Queries.
91 * @param deleteAfterPoll Defaults to 'false'.
92 * @return the spec
93 */
94 public JpaInboundChannelAdapterSpec deleteAfterPoll(boolean deleteAfterPoll) {
95 this.jpaExecutor.setDeleteAfterPoll(deleteAfterPoll);
96 return this;
97 }
98
99 /**
100 * If not set, this property defaults to <code>false</code>, which means that
101 * deletion occurs on a per object basis if a collection of entities is being
102 * deleted.
103 *<p>If set to 'true' the elements of the payload are deleted as a batch
104 * operation. Be aware that this exhibits issues in regards to cascaded deletes.
105 *<p>The specification 'JSR 317: Java Persistence API, Version 2.0' does not
106 * support cascaded deletes in batch operations. The specification states in
107 * chapter 4.10:
108 *<p>"A delete operation only applies to entities of the specified class and
109 * its subclasses. It does not cascade to related entities."
110 * @param deleteInBatch Defaults to 'false' if not set.
111 * @return the spec
112 */
113 public JpaInboundChannelAdapterSpec deleteInBatch(boolean deleteInBatch) {
114 this.jpaExecutor.setDeleteInBatch(deleteInBatch);
115 return this;
116 }
117
118 /**
119 * If set to {@code true} the {@link javax.persistence.EntityManager#flush()} will be called
120 * after persistence operation.
121 * Has the same effect, if the {@code flushSize} is specified to {@code 1}.
122 * For convenience in cases when the provided entity to persist is not an instance of {@link Iterable}.
123 * @param flush defaults to 'false'.
124 * @return the spec
125 */
126 public JpaInboundChannelAdapterSpec flushAfterDelete(boolean flush) {
127 this.jpaExecutor.setFlush(flush);
128 return this;
129 }
130
131 /**
132 * Specify a {@link ParameterSource} that would be used to provide additional parameters.
133 * @param parameterSource the {@link ParameterSource} to use.
134 * @return the spec
135 */
136 public JpaInboundChannelAdapterSpec parameterSource(ParameterSource parameterSource) {
137 this.jpaExecutor.setParameterSource(parameterSource);
138 return this;
139 }
140
141 /**
142 * This parameter indicates that only one result object shall be returned as
143 * a result from the executed JPA operation. If set to <code>true</code> and
144 * the result list from the JPA operations contains only 1 element, then that
145 * 1 element is extracted and returned as payload.
146 * @param expectSingleResult true if a single object is expected.
147 * @return the spec
148 */
149 public JpaInboundChannelAdapterSpec expectSingleResult(boolean expectSingleResult) {
150 this.jpaExecutor.setExpectSingleResult(expectSingleResult);
151 return this;
152 }
153
154 /**
155 * Set the maximum number of results expression. It has be a non null value
156 * Not setting one will default to the behavior of fetching all the records
157 * @param maxResults the maximum number of results to retrieve
158 * @return the spec
159 */
160 public JpaInboundChannelAdapterSpec maxResults(int maxResults) {
161 return maxResultsExpression(new ValueExpression<>(maxResults));
162 }
163
164 /**
165 * Specify a SpEL expression for maximum number of results expression.
166 * Not setting one will default to the behavior of fetching all the records
167 * @param maxResultsExpression The maximum results expression.
168 * @return the spec
169 */
170 public JpaInboundChannelAdapterSpec maxResultsExpression(String maxResultsExpression) {
171 return maxResultsExpression(PARSER.parseExpression(maxResultsExpression));
172 }
173
174 /**
175 * Specify a SpEL expression for maximum number of results expression.
176 * Not setting one will default to the behavior of fetching all the records
177 * @param maxResultsExpression The maximum results expression.
178 * @return the spec
179 */
180 public JpaInboundChannelAdapterSpec maxResultsExpression(Expression maxResultsExpression) {
181 this.jpaExecutor.setMaxResultsExpression(maxResultsExpression);
182 return this;
183 }
184
185 @Override
186 public Map<Object, String> getComponentsToRegister() {
187 return Collections.singletonMap(this.jpaExecutor, null);
188 }
189
190 }